package org.com.lcuiot.service;

import org.com.lcuiot.common.LcuConst;
import org.com.lcuiot.common.TimeUtil;
import org.com.lcuiot.database.dto.Result;
import org.com.lcuiot.database.entity.Account;
import org.com.lcuiot.database.mapper.AccountMapper;
import org.com.lcuiot.security.AsymmetricEncrypt;
import org.com.lcuiot.security.AsymmetricKeyPair;
import org.com.lcuiot.security.JwtUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.time.Duration;
import java.util.Optional;

/**
 * 账号表
 *
 * @author gaoge
 * @since 2022/10/27 14:31
 */
@Service
public class AccountService {
    private static final Logger logger = LoggerFactory.getLogger(AccountService.class);
    private final AccountMapper accountMapper;
    private final PasswordEncoder passwordEncoder;
    private final StringRedisTemplate stringRedisTemplate;


    @Autowired
    public AccountService(AccountMapper accountMapper, PasswordEncoder passwordEncoder, StringRedisTemplate stringRedisTemplate) {
        this.accountMapper = accountMapper;
        this.passwordEncoder = passwordEncoder;
        this.stringRedisTemplate = stringRedisTemplate;
    }


    /**
     * 根据账号查询用户
     */
    public Optional<JwtUser> selectByUsername(String username) {
        JwtUser jwtUser = null;
        if (StringUtils.hasLength(username)) {
            Account account = new Account();
            account.setUsername(username);
            Optional<Account> accountOptional = accountMapper.selectOne(account);
            if (accountOptional.isPresent()) {
                jwtUser = new JwtUser();
                Account accountModel = accountOptional.get();
                jwtUser.setUsername(accountModel.getUsername());
                jwtUser.setPassword(accountModel.getPassword());
                jwtUser.setOrganizationId(accountModel.getOrganizationId());
                jwtUser.setUsername(accountModel.getUsername());
                jwtUser.setName(accountModel.getName());
            }
        }
        return Optional.ofNullable(jwtUser);
    }

    /**
     * 注册账号
     *
     * @param account 请求信息
     * @return Result<Object>
     */
    public Result<Object> register(Account account) {
        Result<Object> result = Result.build();
        try {
            if (!(StringUtils.hasLength(account.getUsername()) && StringUtils.hasLength(account.getName()) && StringUtils.hasLength(account.getPassword()) && StringUtils.hasLength(account.getOrganizationId().toString()))) {
                return result.setCode(500).setMsg("注册参数不全，请补充所需注册参数");
            }
            Account accountEntity = new Account();
            accountEntity.setUsername(account.getUsername());
            Optional<Account> accountOptional = accountMapper.selectOne(accountEntity);
            if (accountOptional.isPresent()) {
                return result.setCode(500).setMsg("账号已被注册");
            }
            account.setPassword(passwordEncoder.encode(account.getPassword()));
            account.setCreateAt(TimeUtil.currentTimeMillis());
            account.setUpdateAt(TimeUtil.currentTimeMillis());
            accountMapper.insert(account);
            account.setPassword("******");
            result.setData(account);
        } catch (Exception e) {
            logger.error("注册账号时发生异常：", e);
            result.setCode(500).setMsg("注册账号时发生异常");
        }
        return result;
    }

    public Result<Object> cryptoKey() {
        Result<Object> result = Result.build();
        try {
            AsymmetricKeyPair keyPair = AsymmetricEncrypt.generateKeyPair(1024);
            String privateKey = keyPair.privateKey();
            String publicKey = keyPair.publicKey();
            stringRedisTemplate.opsForValue().set(LcuConst.PASSWORD_ENCODER_PublicKey + publicKey, privateKey, Duration.ofHours(1));
            result.setData(publicKey);
        } catch (Exception e) {
            logger.error("获取公钥key时发生异常：", e);
            result.setCode(500).setMsg("获取公钥key时发生异常");
        }
        return result;
    }
}
